import 'dart:convert';

import 'package:agora_rtm/agora_rtm.dart';
import 'package:gameplay_flutter/lib_user/user_manager.dart';

import '../m_room/room_chat/model/room_message_event.dart';
import 'rtm_strategy.dart';

class AgoraRtmStrategy implements RtmStrategy {
  final String appId = '86b2ac3562e343f5af1acd303e188c6c';
  late RtmClient rtmClient;

  late final Function(MessageEvent) messageHandler;
  late final Function(PresenceEvent) presenceHandler;

  @override
  Future<void> initializeSdk(String? token) async {
    //create rtm instance
    try {
      // create rtm client
      final (status, client) =
          await RTM(appId, UserManager.instance.id.toString());
      if (status.error == true) {
        print(
            'Room RTM ${status.operation} failed due to ${status.reason}, error code: ${status.errorCode}');
      } else {
        rtmClient = client;
        print('Room RTM Initialize success!');
        await login(token);
      }
      // add events listner
    } catch (e) {
      print('RTM Initialize falid!:${e}');
    }
  }

  @override
  Future<void> login(String? token) async {
    final str = token ?? appId;
    // Paste the following code snippet below "login rtm service" comment
    try {
      // login rtm service
      var (status, response) = await rtmClient.login(str);
      if (status.error == true) {
        print ('Room RTM login RTM failed! token = ${str}');
        print(
            'Room RTM ${status.operation} failed due to ${status.reason}, error code: ${status.errorCode}');
      } else {
        print('Room RTM login RTM success!');
      }
    } catch (e) {
      print('RTM Failed to login: $e');
    }
  }
  @override
  Future<void> publish(String channelId) async {
    try {
      var (status, response) = await rtmClient.publish(
          channelId, 'message number : 000',
          channelType: RtmChannelType.message, customType: 'PlainText');
      if (status.error == true) {
        print(
            'Room RTC ${status.operation} failed, errorCode: ${status.errorCode}, due to ${status.reason}');
      } else {
        print('Room RTC ${status.operation} success! message number:000');
      }
    } catch (e) {
      print('RTC Failed to publish message: $e');
    }
  }

  @override
  Future<void> subscribe(
      String channelId, void Function(RoomMessageEvent event)? message) async {
    // Paste the following code snippet below "subscribe to a channel" comment
    try {
      // subscribe to 'getting-started' channel
      var (status, response) = await rtmClient.subscribe(channelId);
      if (status.error == true) {
        print(
            'Room RTM ${status.operation} failed due to ${status.reason}, error code: ${status.errorCode}');
      } else {
        print('Room RTM subscribe channel: ${channelId} success!');
        addListener(message);
      }
    } catch (e) {
      print('RTM Failed to subscribe channel: $e');
    }
  }

  @override
  Future<void> unSubscribe(String channelId) async {
// Paste the following code snippet below "unsubscribe frome a channel" comment
    try {
      // unsubscribe channel
      var (status, response) = await rtmClient.unsubscribe(channelId);
      if (status.error == true) {
        print(
            'Room ${status.operation} failed due to ${status.reason}, error code: ${status.errorCode}');
      } else {
        print('Room unsubscribe success!');
      }
    } catch (e) {
      print('Room something went wrong with logout: $e');
    }
  }

  @override
  Future<void> logout() async {
    removeListener();
    // Paste the following code snippet below "logout rtm service" comment
    try {
      // logout rtm service
      var (status, response) = await rtmClient.logout();
      if (status.error == true) {
        print(
            'Room RTM ${status.operation} failed due to ${status.reason}, error code: ${status.errorCode}');
      } else {
        print('Room RTM logout RTM success!');
      }
    } catch (e) {
      print('Room RTM something went wrong with logout: $e');
    }
  }

  @override
  Future<void> dispose() async {
    await logout();
    // Paste the following code snippet below "dispose rtm client" comment
    try {
      // dispose rtm client
      var status = await rtmClient.release();
      if (status.error == true) {
        print(
            'Room RTM ${status.operation} failed due to ${status.reason}, error code: ${status.errorCode}');
      } else {
        print('Room RTM dispose RTM success!');
      }
    } catch (e) {}
  }

  void addListener(void Function(RoomMessageEvent event)? message) {
    removeListener();
    messageHandler = (MessageEvent event) {
      try {
        final roomMessage = RoomMessageEvent();
        if (event.message != null) {
          roomMessage.message = utf8.decode(event.message!);
        }
        // 建议增加空判断（根据业务需求选择）
        if (message != null) {
          message(roomMessage);
        } else {
          print('Room 消息回调未注册');
        }
      } catch (e) {
        print("Room 消息解码失败: $e");
      }
    };
    presenceHandler = (PresenceEvent event){
      print('Room PresenceEvent${event.snapshot?.userStateList?.length}');
    };
    rtmClient.addListener(message: messageHandler, presence: presenceHandler);
  }

  void removeListener(){
      rtmClient.removeListener(message: messageHandler,  presence: presenceHandler);
  }
}
